/**
 * @file A compiler from TyX documents to Typst.
 */

import { TyXDocument, TyXDocumentSettings } from "../models"
import lexical2typst from "./lexical2typst"
import tyxValue2typst from "./tyxValue2typst"

const setProperty = (
  element: string,
  attribute: string,
  setting: any,
  transform: ((v: any) => string) | null = JSON.stringify,
) => {
  transform = transform ?? ((v) => v)

  if (setting !== undefined) {
    return `#set ${element}(${attribute}: ${transform(setting)})\n`
  }
  return ""
}

export const tyxSettings2typst = (settings: TyXDocumentSettings) => {
  let result = ""
  result += setProperty("page", "paper", settings.paper)
  result += setProperty("page", "flipped", settings.flipped)
  result += setProperty("page", "columns", settings.columns, null)
  result += setProperty("text", "lang", settings.language)
  result += setProperty("par", "justify", settings.justified)
  if (
    settings.indentation?.unit !== undefined &&
    settings.indentation?.value !== undefined
  ) {
    result += setProperty(
      "par",
      "first-line-indent",
      tyxValue2typst({ ...settings.indentation, type: "length" }),
      null,
    )
  }
  return result
}

const tyx2typst = (
  document: TyXDocument,
  version: string | undefined = undefined,
) => {
  let content = `// Automatically generated by TyX${version ? " " + version : ""}.

// Settings
#metadata(json(bytes(\`\`\`json ${JSON.stringify(
    document.settings ?? {},
  )}\`\`\`.text))) <tyx-settings>
${tyxSettings2typst(document.settings ?? {})}
`
  if (document.preamble) {
    content += `// Preamble
${document.preamble}

`
  }
  if (document.content) {
    content += "// Content\n" + lexical2typst(document.content.root)
  }
  return content
}

export default tyx2typst
